local japi = require "jass.japi"
local jass = require "jass.common"
local storm = require "jass.storm"
local urlenc = require "util.url"
local json = require "util.json"
local load = load
local rsa = require 'util.rsa'
local utility = require 'util.utility'
local version = package.version 
local mapname = "越狱大作战"
local http = "120.55.39.95:3000/hotfix"

local client = {
    loaded = -1,
}

if package.local_test then 
    -- http = "localhost:8080/hotfix"
    version = "789456"
end 

local client_hotfix = "save\\" .. mapname .. "[" .. version .. "].h"

local function unpack_hotfix(content)
    local ok, res = pcall(urlenc.decode, content)
    if ok and res then 
        local sign = res:match("%-%-0%:([^\r\n]+)")
        local buff = res:match("%-%-%*%-%-(.-)%-%-%*-%-")
        if sign and buff then 
            -- 签名验证通过
            if rsa:check_sign(buff, urlenc.decode(sign)) then
                local result = { }
                -- 地图名字
                result.mapname = res:match("%-%-1:([^\r\n]+)")
                -- 地图版本
                result.version = res:match("%-%-2:([^\r\n]+)")
                -- 补丁版本
                result.replace = res:match("%-%-3:([^\r\n]+)")
                -- 补丁数据
                result.content = res:match("%-%-4:(.-)%-%-5:")
                -- 判断版本是否对应
                if result.mapname == mapname and result.version == version and result.replace and result.content then 
                    return result
                end 
            else 
                print("热补丁签名错误...", buff, sign)
            end
        end 
    end 
end 

local function apply_hotfix(player)
    if player:is_self() then 
        local content = storm.load(client_hotfix)
        local hotfix  = unpack_hotfix(content)
        post_message(http, json.encode({
            version = version,
            mapname = mapname,
            replace = hotfix and hotfix.replace,
        }), function (result)
            local ok, res = pcall(json.decode, result)
            if ok and res and type(res) == "table" then 
                local header, chunk = table.unpack(res)
                if header == "404" then 
                    -- 不需要加载热补丁
                    print( "未检测到热补丁...")
                    ac.sync("load-server-empty")
                elseif header == "200" then
                    print( "正在读取热补丁...")
                    if hotfix then 
                        ac.sync_content("load-server-hotfix", content)
                    end 
                elseif header == "201" then
                    print( "正在下载热补丁...")
                    content = chunk
                    if unpack_hotfix(content) then 
                        ac.sync_content("load-server-hotfix", content)
                    end 
                end 
            else 
                ac.sync("load-server-empty")
                print("加载热补丁失败...", ok, res)
            end 
        end)
    end 
end 

ac.sync:on ("load-server-empty") (function (trigger)
    client.loaded = 1 
    if client.timer then 
        client.timer:remove() 
    end
    if client.callback then 
        client.callback()
    end 
end) 

-- 注册同步事件
ac.sync_content:on ("load-server-hotfix") (function (trigger, player, content)
    local hotfix = unpack_hotfix(content)
    if hotfix and hotfix.mapname == mapname and hotfix.version == version and hotfix.replace and hotfix.content then 
        local ok, res = pcall(load, hotfix.content)
        if ok and res then 
            ok, res = pcall(res)
            if ok then 
                print(hotfix.mapname, hotfix.version, hotfix.replace)
                -- 加载成功则更新到本地以便后续使用
                storm.save(client_hotfix, content)
                print("加载热补丁成功...")
            else 
                print("加载热补丁失败...", ok, res)
            end
        else 
            print("加载热补丁失败...", ok, res)
        end 
    end 
    client.loaded = 1 
    if client.timer then 
        client.timer:remove() 
    end
    if client.callback then 
        client.callback()
    end 
end)

function client.load_hotfix(callback)
    client.loaded = 0 
    client.callback = callback
    client.timer = ac.wait(10 * 1000, function () 
        print("加载热补丁超时...")
        client.loaded = -1 
        client.callback()
    end)
    for i=1,12 do 
        if ac.player(i):is_online() then 
            apply_hotfix(ac.player(i))
            break
        end 
    end 
end

return client 